package com.jsn.buildbase.service

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.Browser
import android.support.v4.media.MediaBrowserCompat
import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat
import androidx.media.MediaBrowserServiceCompat
import com.google.android.exoplayer2.*
import com.google.android.exoplayer2.audio.AudioAttributes
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory
import com.google.android.exoplayer2.source.ExtractorMediaSource
import com.google.android.exoplayer2.source.MediaSource
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
import com.jsn.baselibx.MApp
import com.jsn.buildbase.App

class MusicService:MediaBrowserServiceCompat(){

    var mMediaSession :MediaSessionCompat?=null

    lateinit var mStateBuilder :PlaybackStateCompat.Builder

    var mExoPlayer:SimpleExoPlayer ?=null

    private var oldUri: Uri? = null


    val mMediaSessionCallBack= object:MediaSessionCompat.Callback(){
        override fun onStop() {
            super.onStop()
            stop()
        }

        override fun onPause() {
            super.onPause()
            pause()
        }

        override fun onPlayFromUri(uri: Uri?, extras: Bundle?) {
            super.onPlayFromUri(uri, extras)
            uri?.let {
                val mediaSource = extractMediaSourceFromUri(uri)
                if (!uri.path.equals(oldUri?.path))
                    play(mediaSource)
                else play() // this song was paused so we don't need to reload it
                oldUri = uri
            }
        }
    }

    override fun onCreate() {
        super.onCreate()
        initPlayer()
        initExtractor()
        initAttributes()
        mMediaSession= MediaSessionCompat(baseContext,"tagdebugging").apply {
            setFlags(
                MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS or //using service compat u should not set it
                        MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS //for back compatability this will be always set
            )
            // Set initial PlaybackState with ACTION_PLAY, so media buttons can start the player
            mStateBuilder = PlaybackStateCompat.Builder()
                .setActions(PlaybackStateCompat.ACTION_PLAY or PlaybackStateCompat.ACTION_PLAY_PAUSE)
            setPlaybackState(mStateBuilder.build())

            // methods that handle callbacks from a media controller
            setCallback(mMediaSessionCallBack)

            // Set the session's token so that client activities can communicate with it
            setSessionToken(sessionToken) //connect the service to the mediaSession
            isActive = true
        }
    }
    override fun onDestroy() {
        super.onDestroy()
        stop()
    }

    private fun play(mediaSource: MediaSource) {
        if (mExoPlayer == null) initPlayer()
        mExoPlayer?.apply {
            // AudioAttributes here from exoplayer package !!!
            mAttrs?.let { initAttributes() }
            // In 2.9.X you don't need to manually handle audio focus :D
            setAudioAttributes(mAttrs, true)
            prepare(mediaSource)
            play()
        }
    }

    private fun play() {
        mExoPlayer?.apply {
            mExoPlayer?.playWhenReady = true
            updatePlaybackState(PlaybackStateCompat.STATE_PLAYING)
            mMediaSession?.isActive = true
        }
    }


    private fun stop() {
        // release the resources when the service is destroyed
        mExoPlayer?.playWhenReady = false
        mExoPlayer?.release()
        mExoPlayer = null
        updatePlaybackState(PlaybackStateCompat.STATE_NONE)
        mMediaSession?.isActive = false
        mMediaSession?.release()
    }

    private fun pause() {
        mExoPlayer?.apply {
            playWhenReady = false
            if (playbackState == PlaybackStateCompat.STATE_PLAYING) {
                updatePlaybackState(PlaybackStateCompat.STATE_PAUSED)
            }
        }
    }

    override fun onTaskRemoved(rootIntent: Intent?) {
        super.onTaskRemoved(rootIntent)
        stopSelf()
    }


    private fun updatePlaybackState(state: Int) {
        // You need to change the state because the action taken in the controller depends on the state !!!
        mMediaSession?.setPlaybackState(
            PlaybackStateCompat.Builder().setState(
                state // this state is handled in the media controller
                , 0L
                , 1.0f // Speed playing
            ).build()
        )
    }


    private var mAttrs: AudioAttributes? = null


    private fun initAttributes() {

        mAttrs = AudioAttributes.Builder().setUsage(C.USAGE_MEDIA)
            .setContentType(C.CONTENT_TYPE_MUSIC)
            .build()
    }

    private lateinit var mExtractorFactory: ExtractorMediaSource.Factory

    private fun initExtractor() {
        mExtractorFactory = ExtractorMediaSource.Factory(DefaultDataSourceFactory(this, "test"))
            .setExtractorsFactory(DefaultExtractorsFactory())
    }

    private fun initPlayer() {
        mExoPlayer = ExoPlayerFactory.newSimpleInstance(
            this, DefaultRenderersFactory(baseContext)
            , DefaultTrackSelector(),
            DefaultLoadControl()
        )
    }

    override fun onLoadChildren(
        parentId: String,
        result: Result<MutableList<MediaBrowserCompat.MediaItem>>
    ) {

    }

    override fun onGetRoot(
        clientPackageName: String,
        clientUid: Int,
        rootHints: Bundle?
    ): BrowserRoot? {
        return BrowserRoot("",null)
    }
    private fun extractMediaSourceFromUri(uri: Uri): MediaSource {

        return mExtractorFactory.createMediaSource(uri)
    }

}